﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Input;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using MaterialDesignThemes.Wpf;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using RotovapPlatform.Application.Services.Storages;
using RotovapPlatform.Domain.Business.Machine.Enums;
using RotovapPlatform.Domain.Business.Storage.Entities;
using RotovapPlatform.Domain.Business.Storage.Entities.Base;
using RotovapPlatform.Domain.Business.Storage.Entities.Bottles;
using RotovapPlatform.Domain.Business.Storage.Enums;
using RotovapPlatform.UI.Services;
using RotovapPlatform.UI.Views.Dialogs;
using static RotovapPlatform.Domain.Business.Machine.Enums.ExperimentConfigEnums;

namespace RotovapPlatform.UI.ViewModels.MaterialManagement
{
	/// <summary>
	/// 出入库管理视图模型
	/// </summary>
	public partial class StockInOutViewModel : ObservableObject
	{
		private readonly IStorageAppService _storageService;
		private readonly ILogger<StockInOutViewModel> _logger;
		private readonly IMessageService _messageService;
		private ShelfSlotViewModel _selectedSlot;
		private bool _isLoading;
		private string _statusMessage;
		private bool _isBatchMode;
		private bool _isBarcodeScanMode;
		private string _scannedBarcode;
		private string _operatorName;
		private ItemType _selectedBottleType;
		private FunctionType _selectedFunctionType;
		private string _materialName;
		private double _currentVolume;
		private double _initialVolume;
		private double _oilBathTemperature;
		private bool _isClean;
		private bool _isNeedStackOut;
		private ObservableCollection<ShelfSlotViewModel> _selectedSlots = new();
		private List<ItemType> _availableBottleTypes = new List<ItemType>();

		/// <summary>
		/// 操作完成事件，在入库或出库操作完成后触发
		/// </summary>
		public event EventHandler OperationCompleted;

		// 货架槽位集合
		public ObservableCollection<ShelfSlotViewModel> TopShelfItems { get; } = new();
		public ObservableCollection<ShelfSlotViewModel> SecondShelfItems { get; } = new();
		public ObservableCollection<ShelfSlotViewModel> ThirdShelfItems { get; } = new();
		public ObservableCollection<ShelfSlotViewModel> BottomShelfItems { get; } = new();
		public ObservableCollection<ShelfSlotViewModel> SecondShelfSpecialItems { get; } = new();
		public ObservableCollection<ShelfSlotViewModel> ThirdShelfSpecialItems { get; } = new();

		// 命令
		public ICommand LoadDataCommand { get; }
		public ICommand StockInCommand { get; }
		public ICommand StockOutCommand { get; }
		public ICommand RefreshCommand { get; }
		public ICommand ScanBarcodeCommand { get; }
		public ICommand ClearSelectionCommand { get; }
		public ICommand ToggleBatchModeCommand { get; }
		public ICommand ToggleBarcodeScanModeCommand { get; }
		public ICommand SelectSlotCommand { get; }
		public ICommand RemoveSlotCommand { get; }

		// 属性
		public ShelfSlotViewModel SelectedSlot
		{
			get => _selectedSlot;
			set
			{
				if (SetProperty(ref _selectedSlot, value))
				{
					if (value != null && !_isBatchMode)
					{
						// 单选模式下，清除之前的选择
						_selectedSlots.Clear();
						if (value.IsOccupied || CanSelectEmptySlot)
						{
							_selectedSlots.Add(value);
						}
					}
					else if (value != null && _isBatchMode)
					{
						// 批量模式下，切换选择状态
						if (_selectedSlots.Contains(value))
						{
							_selectedSlots.Remove(value);
						}
						else if (value.IsOccupied || CanSelectEmptySlot)
						{
							_selectedSlots.Add(value);
						}
					}

					OnPropertyChanged(nameof(SelectedSlots));
					OnPropertyChanged(nameof(HasSelection));
					OnPropertyChanged(nameof(CanStockIn));
					OnPropertyChanged(nameof(CanStockOut));
					OnPropertyChanged(nameof(IsEmptySlotSelected));
					OnPropertyChanged(nameof(IsOccupiedSlotSelected));

					// 添加瓶子类型相关的属性通知
					OnPropertyChanged(nameof(IsRotovapBottleSelected));
					OnPropertyChanged(nameof(IsCentrifugeBottleSelected));
					OnPropertyChanged(nameof(IsSampleBottleSelected));
					OnPropertyChanged(nameof(IsRotovapEmptySelected));
					OnPropertyChanged(nameof(IsRotovapNotEmptySelected));
					OnPropertyChanged(nameof(IsCentrifugeToRotovapSelected));
					OnPropertyChanged(nameof(IsCentrifugeCondensateCollectionSelected));
					OnPropertyChanged(nameof(IsCentrifugeResidueCollectionSelected));
					OnPropertyChanged(nameof(IsCentrifugeWashLiquidSelected));
					OnPropertyChanged(nameof(IsSampleCondensateSelected));
					OnPropertyChanged(nameof(IsSampleResidueSelected));
					OnPropertyChanged(nameof(SelectedRotovapBottle));
					OnPropertyChanged(nameof(SelectedCentrifugeBottle));
					OnPropertyChanged(nameof(SelectedSampleBottle));
					OnPropertyChanged(nameof(HasExperimentInfo));
				}
			}
		}



		public string StatusMessage
		{
			get => _statusMessage;
			private set => SetProperty(ref _statusMessage, value);
		}

		public bool IsBatchMode
		{
			get => _isBatchMode;
			set
			{
				if (SetProperty(ref _isBatchMode, value))
				{
					if (!value)
					{
						// 退出批量模式时，最多保留一个选择
						if (_selectedSlots.Count > 1)
						{
							var firstSelected = _selectedSlots.FirstOrDefault();
							_selectedSlots.Clear();
							if (firstSelected != null)
							{
								_selectedSlots.Add(firstSelected);
							}
						}
					}
					OnPropertyChanged(nameof(SelectedSlots));
					OnPropertyChanged(nameof(HasSelection));
				}
			}
		}

		public bool IsBarcodeScanMode
		{
			get => _isBarcodeScanMode;
			set => SetProperty(ref _isBarcodeScanMode, value);
		}

		public string ScannedBarcode
		{
			get => _scannedBarcode;
			set => SetProperty(ref _scannedBarcode, value);
		}

		public string OperatorName
		{
			get => _operatorName;
			set => SetProperty(ref _operatorName, value);
		}

		public ItemType SelectedBottleType
		{
			get => _selectedBottleType;
			set
			{
				if (SetProperty(ref _selectedBottleType, value))
				{
					OnPropertyChanged(nameof(AvailableFunctionTypes));
					// 重置功能类型
					if (AvailableFunctionTypes.Any())
					{
						SelectedFunctionType = AvailableFunctionTypes.First();
					}
					else
					{
						SelectedFunctionType = default;
					}

					// 更新表单字段显示控制
					OnPropertyChanged(nameof(ShowMaterialNameField));
					OnPropertyChanged(nameof(ShowCurrentVolumeField));
					OnPropertyChanged(nameof(ShowInitialVolumeField));
					OnPropertyChanged(nameof(ShowOilBathTemperatureField));
					OnPropertyChanged(nameof(ShowIsCleanField));
				}
			}
		}

		public FunctionType SelectedFunctionType
		{
			get => _selectedFunctionType;
			set
			{
				if (SetProperty(ref _selectedFunctionType, value))
				{
					// 更新表单字段显示控制
					OnPropertyChanged(nameof(ShowMaterialNameField));
					OnPropertyChanged(nameof(ShowCurrentVolumeField));
					OnPropertyChanged(nameof(ShowInitialVolumeField));
					OnPropertyChanged(nameof(ShowOilBathTemperatureField));
					OnPropertyChanged(nameof(ShowIsCleanField));
				}
			}
		}

		public string MaterialName
		{
			get => _materialName;
			set => SetProperty(ref _materialName, value);
		}

		public double CurrentVolume
		{
			get => _currentVolume;
			set => SetProperty(ref _currentVolume, value);
		}

		public double InitialVolume
		{
			get => _initialVolume;
			set => SetProperty(ref _initialVolume, value);
		}

		public double OilBathTemperature
		{
			get => _oilBathTemperature;
			set => SetProperty(ref _oilBathTemperature, value);
		}

		public bool IsClean
		{
			get => _isClean;
			set => SetProperty(ref _isClean, value);
		}

		public bool IsNeedStackOut
		{
			get => _isNeedStackOut;
			set => SetProperty(ref _isNeedStackOut, value);
		}

		public ObservableCollection<ShelfSlotViewModel> SelectedSlots => _selectedSlots;

		public bool HasSelection => _selectedSlots.Count > 0;

		public bool CanStockIn => HasSelection && (IsEmptySlotSelected || IsBarcodeScanMode);

		public bool CanStockOut => HasSelection && IsOccupiedSlotSelected;

		public bool IsEmptySlotSelected => HasSelection && _selectedSlots.All(s => !s.IsOccupied);

		public bool IsOccupiedSlotSelected => HasSelection && _selectedSlots.All(s => s.IsOccupied);

		public bool CanSelectEmptySlot => !IsBarcodeScanMode || !string.IsNullOrEmpty(ScannedBarcode);

		// 添加特定类型瓶子的属性
		public bool IsRotovapBottleSelected => SelectedSlot?.Bottle is RotovapBottle;
		public bool IsCentrifugeBottleSelected => SelectedSlot?.Bottle is CentrifugeBottle;
		public bool IsSampleBottleSelected => SelectedSlot?.Bottle is SampleBottle;

		// 添加基于功能码的条件判断属性
		public bool IsRotovapEmptySelected => IsRotovapBottleSelected && SelectedRotovapBottle?.Function == FunctionType.Rotovap_Empty;
		public bool IsRotovapNotEmptySelected => IsRotovapBottleSelected && SelectedRotovapBottle?.Function == FunctionType.Rotovap_NotEmpty;

		public bool IsCentrifugeToRotovapSelected => IsCentrifugeBottleSelected && SelectedCentrifugeBottle?.Function == FunctionType.Centrifuge_To_Rotovap;
		public bool IsCentrifugeCondensateCollectionSelected => IsCentrifugeBottleSelected && SelectedCentrifugeBottle?.Function == FunctionType.Centrifuge_Condensate_Collection;
		public bool IsCentrifugeResidueCollectionSelected => IsCentrifugeBottleSelected && SelectedCentrifugeBottle?.Function == FunctionType.Centrifuge_Residue_Collection;
		public bool IsCentrifugeWashLiquidSelected => IsCentrifugeBottleSelected && SelectedCentrifugeBottle?.Function == FunctionType.Centrifuge_Wash_Liquid;

		public bool IsSampleCondensateSelected => IsSampleBottleSelected && SelectedSampleBottle?.Function == FunctionType.Sample_Condensate;
		public bool IsSampleResidueSelected => IsSampleBottleSelected && SelectedSampleBottle?.Function == FunctionType.Sample_Residue;

		// 判断是否有实验信息
		public bool HasExperimentInfo => SelectedSlot?.Bottle != null && SelectedSlot.Bottle.Function != FunctionType.Centrifuge_Wash_Liquid &&
										SelectedSlot.Bottle.ExperimentId.HasValue &&
										(SelectedSlot.Bottle.ExperimentStartTime != default ||
										 SelectedSlot.Bottle.ExperimentEndTime != default ||
										 !string.IsNullOrEmpty(SelectedSlot.Bottle.ExperimentName));

		public RotovapBottle? SelectedRotovapBottle => SelectedSlot?.Bottle as RotovapBottle;
		public CentrifugeBottle? SelectedCentrifugeBottle => SelectedSlot?.Bottle as CentrifugeBottle;
		public SampleBottle? SelectedSampleBottle => SelectedSlot?.Bottle as SampleBottle;

		public IEnumerable<ItemType> AvailableBottleTypes => _availableBottleTypes.AsReadOnly();

		public IEnumerable<FunctionType> AvailableFunctionTypes
		{
			get
			{
				return SelectedBottleType switch
				{
					ItemType.Rotovap_500ml or ItemType.Rotovap_1000ml => new[]
					{
						FunctionType.Rotovap_Empty,
						FunctionType.Rotovap_NotEmpty
					},
					ItemType.CentrifugeBottle_500ml => new[]
					{
						FunctionType.Centrifuge_Empty,
						FunctionType.Centrifuge_To_Rotovap,
						FunctionType.Centrifuge_Condensate_Collection,
						FunctionType.Centrifuge_Residue_Collection,
						FunctionType.Centrifuge_Wash_Liquid
					},
					ItemType.SampleBottle_8ml => new[]
					{
						FunctionType.Sample_Empty,
						FunctionType.Sample_Condensate,
						FunctionType.Sample_Residue
					},
					_ => Array.Empty<FunctionType>()
				};
			}
		}

		// 获取所有货架槽位
		public IEnumerable<ShelfSlotViewModel> Slots =>
			TopShelfItems
			.Concat(SecondShelfItems)
			.Concat(ThirdShelfItems)
			.Concat(BottomShelfItems)
			.Concat(SecondShelfSpecialItems)
			.Concat(ThirdShelfSpecialItems);

		private ObservableCollection<ShelfSlotViewModel> _occupiedSlots = new();
		public ObservableCollection<ShelfSlotViewModel> OccupiedSlots
		{
			get => _occupiedSlots;
			private set => SetProperty(ref _occupiedSlots, value);
		}

		// 表单字段显示控制
		public bool ShowMaterialNameField => SelectedBottleType != default &&
										   SelectedFunctionType != default &&
										   SelectedFunctionType != FunctionType.Rotovap_Empty &&
										   SelectedFunctionType != FunctionType.Centrifuge_Empty &&
										   SelectedFunctionType != FunctionType.Sample_Empty;

		public bool ShowCurrentVolumeField => SelectedBottleType != default &&
											SelectedFunctionType != default &&
											SelectedFunctionType != FunctionType.Rotovap_Empty &&
											SelectedFunctionType != FunctionType.Centrifuge_Empty &&
											SelectedFunctionType != FunctionType.Sample_Empty;

		public bool ShowInitialVolumeField => (SelectedBottleType == ItemType.CentrifugeBottle_500ml &&
											 (SelectedFunctionType == FunctionType.Centrifuge_To_Rotovap ||
											  SelectedFunctionType == FunctionType.Centrifuge_Wash_Liquid));

		public bool ShowOilBathTemperatureField => false; // 入库时不需要设置油浴温度

		public bool ShowIsCleanField => (SelectedBottleType == ItemType.Rotovap_500ml ||
										SelectedBottleType == ItemType.Rotovap_1000ml) &&
										SelectedFunctionType == FunctionType.Rotovap_Empty;

		public StockInOutViewModel(IStorageAppService storageService, ILogger<StockInOutViewModel> logger, IMessageService messageService)
		{
			_storageService = storageService;
			_logger = logger;
			_messageService = messageService;

			// 初始化命令
			LoadDataCommand = new AsyncRelayCommand(LoadShelfData);
			StockInCommand = new AsyncRelayCommand(StockInAsync, () => CanStockIn);
			StockOutCommand = new AsyncRelayCommand(StockOutAsync, () => CanStockOut);
			RefreshCommand = new AsyncRelayCommand(RefreshAsync);
			ScanBarcodeCommand = new RelayCommand(() => OnBarcodeScanned(ScannedBarcode));
			ClearSelectionCommand = new RelayCommand(ClearSelection);
			ToggleBatchModeCommand = new RelayCommand(() => IsBatchMode = !IsBatchMode);
			ToggleBarcodeScanModeCommand = new RelayCommand(() => IsBarcodeScanMode = !IsBarcodeScanMode);
			SelectSlotCommand = new RelayCommand<ShelfSlotViewModel>(SelectSlot);
			RemoveSlotCommand = new RelayCommand<ShelfSlotViewModel>(RemoveSlot);

			// 初始化货架UI
			InitializeShelf();

			// 加载数据
			_ = LoadShelfData();

			// 设置默认值
			OperatorName = Environment.UserName;
			SelectedBottleType = ItemType.Rotovap_500ml;
		}

		private void InitializeShelf()
		{
			// 初始化第一层（7个位置）
			for (int i = 0; i < 7; i++)
				TopShelfItems.Add(new ShelfSlotViewModel(i, 1));

			// 初始化第二层（4个标准位置）
			for (int i = 0; i < 4; i++)
				SecondShelfItems.Add(new ShelfSlotViewModel(i, 2));

			// 初始化第二层特殊位置（2个较矮位置）
			for (int i = 0; i < 2; i++)
				SecondShelfSpecialItems.Add(new ShelfSlotViewModel(4 + i, 2));

			// 初始化第三层（4个标准位置）
			for (int i = 0; i < 4; i++)
				ThirdShelfItems.Add(new ShelfSlotViewModel(i, 3));

			// 初始化第三层特殊位置（2个较高位置）
			for (int i = 0; i < 2; i++)
				ThirdShelfSpecialItems.Add(new ShelfSlotViewModel(4 + i, 3));

			// 初始化第四层（5个位置）
			for (int i = 0; i < 5; i++)
				BottomShelfItems.Add(new ShelfSlotViewModel(i, 4));
		}

		private async Task LoadShelfData()
		{
			try
			{
		
				StatusMessage = "正在加载数据...";

				// 清空现有数据
				ClearAllBottles();

				// 获取所有货架位置
				var locations = await _storageService.GetAllShelfLocationsAsync();

				// 更新UI
				foreach (var location in locations.Where(l => l.IsOccupied && l.CurrentItem != null))
				{
					// 获取位置编号
					int position = location.Position;

					// 获取显示名称
					string displayName = _storageService.GetShelfDisplayName(position);

					// 解析行列信息
					int row = position / 100;
					int column = position % 100;

					// 根据位置编号找到对应的槽位
					ShelfSlotViewModel slot = FindSlotByPosition(row, column);

					if (slot != null && location.CurrentItem is Bottle bottle)
					{
						// 设置瓶子和位置信息
						slot.SetBottle(bottle);
						slot.LocationId = location.Id; // 仍然保存ID以便于调试

						// 处理DisplayPosition，确保格式为"1-1"
						if (displayName.StartsWith("货架"))
						{
							// 去掉"货架"前缀
							slot.DisplayPosition = displayName.Substring(2);
						}
						else
						{
							slot.DisplayPosition = displayName;
						}
					}
				}

				// 更新已占用槽位列表
				UpdateOccupiedSlots();

				StatusMessage = $"数据加载完成，共 {OccupiedSlots.Count} 个已占用槽位";
			}
			catch (Exception ex)
			{
				StatusMessage = $"加载数据失败: {ex.Message}";
				_logger.LogError($"加载数据失败: {ex.Message}");
			}
			finally
			{
			
			}
		}

		private void ClearAllBottles()
		{
			foreach (var slot in Slots)
			{
				slot.Bottle = null;
				slot.IsOccupied = false;
				slot.LocationId = 0;
				slot.DisplayPosition = string.Empty;
			}

			OccupiedSlots.Clear();
		}

		private ShelfSlotViewModel FindSlotByPosition(int row, int column)
		{
			switch (row)
			{
				case 1:
					// 第一层
					return column >= 1 && column <= 7 ? TopShelfItems[column - 1] : null;
				case 2:
					// 第二层
					if (column >= 1 && column <= 4)
						return SecondShelfItems[column - 1];
					else if (column >= 5 && column <= 6)
						return SecondShelfSpecialItems[column - 5];
					return null;
				case 3:
					// 第三层
					if (column >= 1 && column <= 4)
						return ThirdShelfItems[column - 1];
					else if (column >= 5 && column <= 6)
						return ThirdShelfSpecialItems[column - 5];
					return null;
				case 4:
					// 第四层
					return column >= 1 && column <= 5 ? BottomShelfItems[column - 1] : null;
				default:
					return null;
			}
		}

		private void UpdateOccupiedSlots()
		{
			OccupiedSlots.Clear();
			foreach (var slot in Slots.Where(s => s.IsOccupied))
			{
				slot.DisplayPosition = $"{slot.Layer}-{slot.Position + 1}";
				OccupiedSlots.Add(slot);
			}
		}

		private async Task RefreshAsync()
		{
			await LoadShelfData();
		}

		private void OnBarcodeScanned(string barcode)
		{
			if (!string.IsNullOrEmpty(barcode))
			{
				ScannedBarcode = barcode;
				StatusMessage = $"扫描到条码: {barcode}";
			}
		}

		private void ClearSelection()
		{
			_selectedSlots.Clear();
			OnPropertyChanged(nameof(SelectedSlots));
			OnPropertyChanged(nameof(HasSelection));
			OnPropertyChanged(nameof(CanStockIn));
			OnPropertyChanged(nameof(CanStockOut));
		}

		private async Task StockInAsync()
		{
			if (!HasSelection)
			{
				await _messageService.ShowWarningAsync("请先选择货架位置");
				return;
			}

			try
			{
				_logger.LogDebug($"开始入库操作，选中了 {_selectedSlots.Count} 个位置");
				
				StatusMessage = "正在处理入库请求...";

				// 验证必填字段
				if (ShowMaterialNameField && string.IsNullOrWhiteSpace(MaterialName))
				{
					_logger.LogWarning("入库失败：物料名称不能为空");
					await _messageService.ShowWarningAsync("物料名称不能为空");
					return;
				}

				if (ShowCurrentVolumeField && CurrentVolume <= 0)
				{
					_logger.LogWarning("入库失败：当前体积必须大于0");
					await _messageService.ShowWarningAsync("当前体积必须大于0");
					return;
				}

				// 自动设置操作员为当前用户
				OperatorName = Environment.UserName;

				int successCount = 0;
				int failCount = 0;
				List<string> errors = new List<string>();

				foreach (var slot in _selectedSlots)
				{
					if (slot.IsOccupied)
					{
						failCount++;
						errors.Add($"位置 {slot.DisplayPosition} 已被占用");
						continue;
					}

					try
					{
						// 创建物品
						var item = CreateBottle();
						_logger.LogDebug($"创建了新的物品: {item.Type}");

						// 放入货架
						// 计算位置编号
						int position = slot.Layer * 100 + slot.Position + 1; // +1是因为Position从0开始，而数据库中从1开始
						var location = await _storageService.PlaceItemByPositionAsync(LocationCode.Shelf, position, item);

						if (location != null)
						{
							successCount++;
							slot.Bottle = (Bottle)item;
							slot.IsOccupied = true;
							slot.LocationId = location.Id; // 仍然保存ID以便于调试

							// 获取显示名称
							string displayName = _storageService.GetShelfDisplayName(location.Position);

							// 处理DisplayPosition，确保格式为"1-1"
							if (displayName.StartsWith("货架"))
							{
								// 去掉"货架"前缀
								slot.DisplayPosition = displayName.Substring(2);
							}
							else
							{
								slot.DisplayPosition = displayName;
							}
						}
						else
						{
							failCount++;
							errors.Add($"位置 {slot.DisplayPosition} 入库失败");
						}
					}
					catch (Exception ex)
					{
						_logger.LogError($"入库时发生错误: {ex.Message}");
						failCount++;
						errors.Add($"位置 {slot.DisplayPosition} 入库失败: {ex.Message}");
					}
				}

				// 更新已占用槽位列表
				UpdateOccupiedSlots();

				// 显示结果
				if (successCount > 0 && failCount == 0)
				{
					string message = successCount == 1
						? $"成功将物品入库到位置 {_selectedSlots[0].DisplayPosition}"
						: $"成功将 {successCount} 个物品入库";

					_logger.LogInformation(message);
					await _messageService.ShowInfoAsync(message, "入库成功");
					ClearSelection();

					// 触发操作完成事件，通知其他视图模型刷新
					OperationCompleted?.Invoke(this, EventArgs.Empty);

					// 触发货架数据更新事件 - 使用EventBus机制通知所有订阅者
					EventBus.NotifyShelfDataUpdated();
				}
				else if (successCount > 0 && failCount > 0)
				{
					string message = $"部分入库成功：{successCount} 个成功，{failCount} 个失败\n" +
									string.Join("\n", errors);

					_logger.LogWarning(message);
					await _messageService.ShowWarningAsync(message, "部分入库成功");

					// 触发操作完成事件，通知其他视图模型刷新
					OperationCompleted?.Invoke(this, EventArgs.Empty);
				}
				else
				{
					string message = $"入库失败：\n{string.Join("\n", errors)}";
					_logger.LogError(message);
					await _messageService.ShowErrorAsync(message, "入库失败");
				}
			}
			catch (Exception ex)
			{
				_logger.LogError($"入库过程中发生异常：{ex.Message}");
				await _messageService.ShowErrorAsync($"入库失败：{ex.Message}", "错误");
			}
			finally
			{
				
				StatusMessage = "入库操作完成";
			}
		}

		private IStorageItem CreateBottle()
		{
			// 设置默认操作员
			if (string.IsNullOrEmpty(OperatorName))
			{
				OperatorName = Environment.UserName;
			}

			switch (SelectedBottleType)
			{
				case ItemType.Rotovap_500ml:
				case ItemType.Rotovap_1000ml:
					// 旋蒸瓶只支持入库空瓶，默认是清洁的
					if (SelectedFunctionType == FunctionType.Rotovap_Empty)
					{
						IsClean = true;
					}

					return _storageService.CreateRotovapBottle(
						SelectedBottleType == ItemType.Rotovap_1000ml,
						SelectedFunctionType,
						string.IsNullOrEmpty(MaterialName) ? "空旋蒸瓶" : MaterialName,
						IsClean);

				case ItemType.CentrifugeBottle_500ml:
					string centrifugeMaterialName = MaterialName;

					// 如果是空瓶，设置默认名称
					if (SelectedFunctionType == FunctionType.Centrifuge_Empty)
					{
						centrifugeMaterialName = "空离心瓶";
						CurrentVolume = 0;
						InitialVolume = 0;
					}

					var centrifugeBottle = _storageService.CreateCentrifugeBottle(
						SelectedFunctionType,
						centrifugeMaterialName,
						CurrentVolume);

					// 根据功能类型设置额外属性
					if (SelectedFunctionType == FunctionType.Centrifuge_To_Rotovap ||
						SelectedFunctionType == FunctionType.Centrifuge_Wash_Liquid)
					{
						centrifugeBottle.InitialVolume = InitialVolume;
					}

					return centrifugeBottle;

				case ItemType.SampleBottle_8ml:
					string sampleMaterialName = MaterialName;

					// 如果是空瓶，设置默认名称
					if (SelectedFunctionType == FunctionType.Sample_Empty)
					{
						sampleMaterialName = "空取样瓶";
						CurrentVolume = 0;
					}

					var sampleBottle = _storageService.CreateSampleBottle(
						SelectedFunctionType,
						sampleMaterialName,
						CurrentVolume);

					return sampleBottle;

				default:
					return null;
			}
		}

		private async Task StockOutAsync()
		{
			if (!HasSelection)
			{
				await _messageService.ShowWarningAsync("请先选择货架位置");
				return;
			}

			if (!IsOccupiedSlotSelected)
			{
				await _messageService.ShowWarningAsync("只能对已占用的位置执行出库操作");
				return;
			}

			// 自动设置操作员为当前用户
			OperatorName = Environment.UserName;

			// 确认出库
			bool confirmed = await ShowConfirmDialog();
			if (!confirmed)
			{
				_logger.LogInformation("用户取消了出库操作");
				return;
			}

			try
			{
				_logger.LogDebug($"开始出库操作，选中了 {_selectedSlots.Count} 个位置");
			
				StatusMessage = "正在处理出库请求...";

				int successCount = 0;
				int failCount = 0;
				List<string> errors = new List<string>();

				foreach (var slot in _selectedSlots)
				{
					if (!slot.IsOccupied)
					{
						failCount++;
						errors.Add($"位置 {slot.DisplayPosition} 没有物品");
						continue;
					}

					try
					{
						// 记录出库信息
						if (slot.Bottle != null)
						{
							slot.Bottle.Operator = OperatorName;
							slot.Bottle.StackOutTime = DateTime.Now;
						}

						// 从货架取出物品
						// 计算位置编号
						int position = slot.Layer * 100 + slot.Position + 1; // +1是因为Position从0开始，而数据库中从1开始
						var item = await _storageService.RemoveItemByPositionAsync(LocationCode.Shelf, position);

						if (item != null)
						{
							successCount++;
							slot.ClearBottle();
						}
						else
						{
							failCount++;
							errors.Add($"位置 {slot.DisplayPosition} 出库失败");
						}
					}
					catch (Exception ex)
					{
						_logger.LogError($"出库时发生错误: {ex.Message}");
						failCount++;
						errors.Add($"位置 {slot.DisplayPosition} 出库失败: {ex.Message}");
					}
				}

				// 更新已占用槽位列表
				UpdateOccupiedSlots();

				// 显示结果
				if (successCount > 0 && failCount == 0)
				{
					string message = successCount == 1
						? $"成功将位置 {_selectedSlots[0].DisplayPosition} 的物品出库"
						: $"成功将 {successCount} 个物品出库";

					_logger.LogInformation(message);
					await _messageService.ShowInfoAsync(message, "出库成功");
					ClearSelection();

					// 触发操作完成事件，通知其他视图模型刷新
					OperationCompleted?.Invoke(this, EventArgs.Empty);

					// 触发货架数据更新事件 - 使用EventBus机制通知所有订阅者
					EventBus.NotifyShelfDataUpdated();
				}
				else if (successCount > 0 && failCount > 0)
				{
					string message = $"部分出库成功：{successCount} 个成功，{failCount} 个失败\n" +
									string.Join("\n", errors);

					_logger.LogWarning(message);
					await _messageService.ShowWarningAsync(message, "部分出库成功");

					// 触发操作完成事件，通知其他视图模型刷新
					OperationCompleted?.Invoke(this, EventArgs.Empty);
				}
				else
				{
					string message = $"出库失败：\n{string.Join("\n", errors)}";
					_logger.LogError(message);
					await _messageService.ShowErrorAsync(message, "出库失败");
				}
			}
			catch (Exception ex)
			{
				_logger.LogError($"出库过程中发生异常：{ex.Message}");
				await _messageService.ShowErrorAsync($"出库失败：{ex.Message}", "错误");
			}
			finally
			{
				
				StatusMessage = "出库操作完成";
			}
		}

		public void SelectSlot(ShelfSlotViewModel slot)
		{
			if (slot == null)
				return;

			// 确保DisplayPosition不为空
			if (string.IsNullOrEmpty(slot.DisplayPosition))
			{
				slot.DisplayPosition = $"{slot.Layer}-{slot.Position + 1}";
			}

			// 条码扫描模式下，只能选择空位置
			if (IsBarcodeScanMode && slot.IsOccupied)
			{
				StatusMessage = "条码扫描模式下只能选择空位置";
				return;
			}

			// 非批量模式下，只能选择一个位置
			if (!IsBatchMode && _selectedSlots.Count > 0)
			{
				// 清除之前选择的槽位的选中状态
				foreach (var selectedSlot in _selectedSlots)
				{
					selectedSlot.IsSelected = false;
				}
				_selectedSlots.Clear();
			}

			// 批量模式下，确保所有选择的位置状态一致（要么都是空的，要么都是占用的）
			if (IsBatchMode && _selectedSlots.Count > 0)
			{
				bool firstIsOccupied = _selectedSlots[0].IsOccupied;
				if (slot.IsOccupied != firstIsOccupied)
				{
					StatusMessage = "批量模式下只能选择状态一致的位置";
					return;
				}
			}

			// 如果已经选择了该位置，则取消选择
			if (_selectedSlots.Contains(slot))
			{
				_selectedSlots.Remove(slot);
				slot.IsSelected = false;
			}
			else
			{
				_selectedSlots.Add(slot);
				slot.IsSelected = true;
			}

			// 设置当前选中的槽位，用于显示详细信息
			SelectedSlot = slot;

			// 更新UI状态
			OnPropertyChanged(nameof(SelectedSlots));
			OnPropertyChanged(nameof(HasSelection));
			OnPropertyChanged(nameof(CanStockIn));
			OnPropertyChanged(nameof(CanStockOut));
			OnPropertyChanged(nameof(IsEmptySlotSelected));
			OnPropertyChanged(nameof(IsOccupiedSlotSelected));

			// 更新状态消息
			if (slot.IsOccupied)
			{
				StatusMessage = $"已选择位置 {slot.DisplayPosition}";
			}
			else
			{
				StatusMessage = $"已选择空位置 {slot.DisplayPosition}";
			}

			// 更新可用瓶子类型
			_ = UpdateAvailableBottleTypes();
		}

		private void RemoveSlot(ShelfSlotViewModel slot)
		{
			if (slot == null || !_selectedSlots.Contains(slot))
				return;

			_selectedSlots.Remove(slot);
			slot.IsSelected = false;

			OnPropertyChanged(nameof(SelectedSlots));
			OnPropertyChanged(nameof(HasSelection));
			OnPropertyChanged(nameof(CanStockIn));
			OnPropertyChanged(nameof(CanStockOut));
			OnPropertyChanged(nameof(IsEmptySlotSelected));
			OnPropertyChanged(nameof(IsOccupiedSlotSelected));
		}

		protected override void OnPropertyChanged(PropertyChangedEventArgs e)
		{
			base.OnPropertyChanged(e);

			if (e.PropertyName == nameof(HasSelection) ||
				e.PropertyName == nameof(IsEmptySlotSelected) ||
				e.PropertyName == nameof(IsOccupiedSlotSelected) ||
				e.PropertyName == nameof(IsBarcodeScanMode) ||
				e.PropertyName == nameof(ScannedBarcode))
			{
				(StockInCommand as AsyncRelayCommand)?.NotifyCanExecuteChanged();
				(StockOutCommand as AsyncRelayCommand)?.NotifyCanExecuteChanged();
			}
		}

		// 更新可用瓶子类型
		private async Task UpdateAvailableBottleTypes()
		{
			// 创建一个新的列表，而不是修改现有列表
			var newBottleTypes = new List<ItemType>();

			if (!HasSelection || _selectedSlots.Count == 0)
			{
				// 默认显示所有类型
				newBottleTypes.AddRange(new[]
				{
					ItemType.Rotovap_500ml,
					ItemType.Rotovap_1000ml,
					ItemType.CentrifugeBottle_500ml,
					ItemType.SampleBottle_8ml
				});
			}
			else
			{
				// 计算位置编号
				int position = _selectedSlots[0].Layer * 100 + _selectedSlots[0].Position + 1; // +1是因为Position从0开始，而数据库中从1开始
				_logger.LogInformation($"计算位置编号: Layer={_selectedSlots[0].Layer}, Position={_selectedSlots[0].Position}, 最终位置={position}");

				// 获取位置信息
				var location = await _storageService.GetShelfLocationAsync(LocationCode.Shelf, position);
				if (location != null)
				{
					// 更新可用瓶子类型
					_logger.LogInformation($"位置 {position} 支持的瓶子类型: {string.Join(", ", location.SupportedItemTypes)}");
					newBottleTypes.AddRange(location.SupportedItemTypes);
				}
				else
				{
					_logger.LogWarning($"未找到位置 {position} 的配置信息，使用默认瓶子类型");
					// 默认显示所有类型
					newBottleTypes.AddRange(new[]
					{
						ItemType.Rotovap_500ml,
						ItemType.Rotovap_1000ml,
						ItemType.CentrifugeBottle_500ml,
						ItemType.SampleBottle_8ml
					});
				}
			}

			// 一次性替换整个集合，而不是逐项修改
			_availableBottleTypes = newBottleTypes;

			OnPropertyChanged(nameof(AvailableBottleTypes));

			// 如果当前选择的瓶子类型不在可用列表中，则重置选择
			if (_availableBottleTypes.Count > 0 && !_availableBottleTypes.Contains(SelectedBottleType))
			{
				SelectedBottleType = _availableBottleTypes.First();
			}
		}

		private async Task<bool> ShowConfirmDialog()
		{
			string message = _selectedSlots.Count == 1
				? $"确定要将 {_selectedSlots[0].DisplayPosition} 位置的物品出库吗？"
				: $"确定要将选中的 {_selectedSlots.Count} 个物品出库吗？";

			return await _messageService.ShowConfirmAsync(message, "确认出库");
		}
	}
}